// Data serialization and transformation utilities

import type { User, Message, Chat, ClientData } from './index'

// Date serialization helpers
export function serializeDate(date: Date): string {
  return date.toISOString()
}

export function deserializeDate(dateString: string): Date {
  return new Date(dateString)
}

// User serialization
export interface SerializedUser {
  id: string
  name: string
  avatar: string
  role: 'agent' | 'client'
  email?: string
  phone?: string
  status: 'online' | 'offline' | 'away'
  lastSeen: string
  createdAt: string
  updatedAt: string
}

export function serializeUser(user: User): SerializedUser {
  return {
    ...user,
    lastSeen: serializeDate(user.lastSeen),
    createdAt: serializeDate(user.createdAt),
    updatedAt: serializeDate(user.updatedAt)
  }
}

export function deserializeUser(serialized: SerializedUser): User {
  return {
    ...serialized,
    lastSeen: deserializeDate(serialized.lastSeen),
    createdAt: deserializeDate(serialized.createdAt),
    updatedAt: deserializeDate(serialized.updatedAt)
  }
}

// Message serialization
export interface SerializedMessage {
  id: string
  chatId: string
  senderId: string
  content: string
  timestamp: string
  type: 'text' | 'image' | 'file'
  status: 'sending' | 'sent' | 'delivered' | 'read' | 'failed'
  metadata?: any
  replyTo?: string
  edited?: boolean
  editedAt?: string
  createdAt: string
  updatedAt: string
}

export function serializeMessage(message: Message): SerializedMessage {
  return {
    ...message,
    timestamp: serializeDate(message.timestamp),
    editedAt: message.editedAt ? serializeDate(message.editedAt) : undefined,
    createdAt: serializeDate(message.createdAt),
    updatedAt: serializeDate(message.updatedAt)
  }
}

export function deserializeMessage(serialized: SerializedMessage): Message {
  return {
    ...serialized,
    timestamp: deserializeDate(serialized.timestamp),
    editedAt: serialized.editedAt ? deserializeDate(serialized.editedAt) : undefined,
    createdAt: deserializeDate(serialized.createdAt),
    updatedAt: deserializeDate(serialized.updatedAt)
  }
}

// Chat serialization
export interface SerializedChat {
  id: string
  participants: SerializedUser[]
  lastMessage: SerializedMessage | null
  unreadCount: number
  status: 'active' | 'closed' | 'pending' | 'archived'
  title?: string
  description?: string
  tags: string[]
  priority: 'low' | 'normal' | 'high' | 'urgent'
  assignedAgent?: string
  createdAt: string
  updatedAt: string
  closedAt?: string
}

export function serializeChat(chat: Chat): SerializedChat {
  return {
    ...chat,
    participants: chat.participants.map(serializeUser),
    lastMessage: chat.lastMessage ? serializeMessage(chat.lastMessage) : null,
    createdAt: serializeDate(chat.createdAt),
    updatedAt: serializeDate(chat.updatedAt),
    closedAt: chat.closedAt ? serializeDate(chat.closedAt) : undefined
  }
}

export function deserializeChat(serialized: SerializedChat): Chat {
  return {
    ...serialized,
    participants: serialized.participants.map(deserializeUser),
    lastMessage: serialized.lastMessage ? deserializeMessage(serialized.lastMessage) : null,
    createdAt: deserializeDate(serialized.createdAt),
    updatedAt: deserializeDate(serialized.updatedAt),
    closedAt: serialized.closedAt ? deserializeDate(serialized.closedAt) : undefined
  }
}

// Client data serialization
export interface SerializedClientData {
  id: string
  name: string
  avatar: string
  phone?: string
  email?: string
  company?: string
  position?: string
  location?: string
  timezone?: string
  language: string
  tags: any[]
  notes: string
  customFields: Record<string, any>
  history: any[]
  preferences: any
  createdAt: string
  updatedAt: string
  lastContactAt?: string
}

export function serializeClientData(client: ClientData): SerializedClientData {
  return {
    ...client,
    createdAt: serializeDate(client.createdAt),
    updatedAt: serializeDate(client.updatedAt),
    lastContactAt: client.lastContactAt ? serializeDate(client.lastContactAt) : undefined
  }
}

export function deserializeClientData(serialized: SerializedClientData): ClientData {
  return {
    ...serialized,
    createdAt: deserializeDate(serialized.createdAt),
    updatedAt: deserializeDate(serialized.updatedAt),
    lastContactAt: serialized.lastContactAt ? deserializeDate(serialized.lastContactAt) : undefined
  }
}

// Batch serialization functions
export function serializeUsers(users: User[]): SerializedUser[] {
  return users.map(serializeUser)
}

export function deserializeUsers(serialized: SerializedUser[]): User[] {
  return serialized.map(deserializeUser)
}

export function serializeMessages(messages: Message[]): SerializedMessage[] {
  return messages.map(serializeMessage)
}

export function deserializeMessages(serialized: SerializedMessage[]): Message[] {
  return serialized.map(deserializeMessage)
}

export function serializeChats(chats: Chat[]): SerializedChat[] {
  return chats.map(serializeChat)
}

export function deserializeChats(serialized: SerializedChat[]): Chat[] {
  return serialized.map(deserializeChat)
}

// JSON safe serialization for localStorage
export function toJSON<T>(data: T): string {
  return JSON.stringify(data, (_key, value) => {
    if (value instanceof Date) {
      return { __type: 'Date', value: value.toISOString() }
    }
    return value
  })
}

export function fromJSON<T>(json: string): T {
  return JSON.parse(json, (_key, value) => {
    if (value && typeof value === 'object' && value.__type === 'Date') {
      return new Date(value.value)
    }
    return value
  })
}

// Data transformation utilities
export function transformUserForAPI(user: User): Record<string, any> {
  return {
    id: user.id,
    name: user.name,
    avatar: user.avatar,
    role: user.role,
    email: user.email,
    phone: user.phone,
    status: user.status
  }
}

export function transformMessageForAPI(message: Message): Record<string, any> {
  return {
    id: message.id,
    chat_id: message.chatId,
    sender_id: message.senderId,
    content: message.content,
    type: message.type,
    metadata: message.metadata,
    reply_to: message.replyTo
  }
}

export function transformChatForAPI(chat: Chat): Record<string, any> {
  return {
    id: chat.id,
    participant_ids: chat.participants.map(p => p.id),
    title: chat.title,
    description: chat.description,
    tags: chat.tags,
    priority: chat.priority,
    status: chat.status,
    assigned_agent: chat.assignedAgent
  }
}

// Data normalization utilities
export function normalizeUser(user: any): User {
  return {
    id: user.id || '',
    name: user.name || '',
    avatar: user.avatar || '/default-avatar.png',
    role: user.role || 'client',
    email: user.email,
    phone: user.phone,
    status: user.status || 'offline',
    lastSeen: user.lastSeen ? new Date(user.lastSeen) : new Date(),
    createdAt: user.createdAt ? new Date(user.createdAt) : new Date(),
    updatedAt: user.updatedAt ? new Date(user.updatedAt) : new Date()
  }
}

export function normalizeMessage(message: any): Message {
  return {
    id: message.id || '',
    chatId: message.chat_id || message.chatId || '',
    senderId: message.sender_id || message.senderId || '',
    content: message.content || '',
    timestamp: message.timestamp ? new Date(message.timestamp) : new Date(),
    type: message.type || 'text',
    status: message.status || 'sent',
    metadata: message.metadata,
    replyTo: message.reply_to || message.replyTo,
    edited: message.edited || false,
    editedAt: message.edited_at ? new Date(message.edited_at) : undefined,
    createdAt: message.created_at ? new Date(message.created_at) : new Date(),
    updatedAt: message.updated_at ? new Date(message.updated_at) : new Date()
  }
}

export function normalizeChat(chat: any): Chat {
  return {
    id: chat.id || '',
    participants: chat.participants || [],
    lastMessage: chat.last_message ? normalizeMessage(chat.last_message) : null,
    unreadCount: chat.unread_count || 0,
    status: chat.status || 'pending',
    title: chat.title,
    description: chat.description,
    tags: chat.tags || [],
    priority: chat.priority || 'normal',
    assignedAgent: chat.assigned_agent || chat.assignedAgent,
    createdAt: chat.created_at ? new Date(chat.created_at) : new Date(),
    updatedAt: chat.updated_at ? new Date(chat.updated_at) : new Date(),
    closedAt: chat.closed_at ? new Date(chat.closed_at) : undefined
  }
}